﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using IntoNails.Infrastructure;
using IntoNails.Infrastructure.InteractionRequests;
using IntoNails.Infrastructure.ViewModels;
using IntoNails.Models;
using IntoNails.Modules.CategoryManagement.Models;

namespace IntoNails.Modules.CategoryManagement.ViewModels
{
    public partial class CategoryWorkspaceViewModel
    {
        #region Category

        private void OnRenameCategoryEventSubscribed(string categoryName)
        {
        }

        #region New Category

        private void OnCreateNewCategoryEventSubscribed(Category category)
        {
            this.CreateNewCategoryNotification.Raise(category, this.CreateNewCategoryCallback, () => { });
        }

        private void CreateNewCategoryCallback(Category category)
        {
            // publish the created category to the category-tree...
            ////this._eventAggregator.GetEvent<NewCategoryCreatedEventAggregator>().Publish(category);

            TreeNodeViewModel newCategoryNode;

            if (this.SelectedCategoryNode != null)
            {
                // sets parent category to the new category-model.
                category.Parent = this.SelectedCategoryNode.AssociatedObject as Category;

                newCategoryNode = new TreeNodeViewModel(category.DisplayName, this.SelectedCategoryNode, category, category);

                this.SelectedCategoryNode.Children.Add(newCategoryNode);
            }
            else
            {
                // sets parent category to the new category-model.
                category.Parent = this.RootCategoryNode.AssociatedObject as Category;

                newCategoryNode = new TreeNodeViewModel(category.DisplayName, this.RootCategoryNode, category, category);

                this.RootCategoryNode.Children.Add(newCategoryNode);
            }

            this._categoryRepository.Add(category);

            this.RefreshCategoryTree();
        }

        #endregion

        #region Delete Category

        private void OnDeleteCategoryEventSubscribed(MessageBoxContext context)
        {
            this.ShowMessageBox.Raise(context, this.MessageBoxSubmitCallback, ()=> { });
        }

        private void MessageBoxSubmitCallback(MessageBoxContext messageCallback)
        {
            if (this.SelectedCategoryNode == null)
            {
                // we must have a node to delete
                // TODO: show message-box
                MessageBoxContext context = new MessageBoxContext("Please select a Category to delete first.",
                                                                  GlobalInfoCaches.AssemblyName, MessageBoxButtons.OK,
                                                                  MessageBoxIcons.Exclamation);
                this.ShowMessageBox.Raise(context,
                                          boxContext => { },
                                          () => { });

                return;
            }

            if (this.SelectedCategoryNode.IsRoot)
            {
                // cannot delete root-node
                MessageBoxContext context = new MessageBoxContext("Cannot delete this Category.",
                                                                  GlobalInfoCaches.AssemblyName, MessageBoxButtons.OK,
                                                                  MessageBoxIcons.Exclamation);
                this.ShowMessageBox.Raise(context,
                                          boxContext => { },
                                          () => { });
                return;
            }

            ITreeNodeViewModel parent = this.SelectedCategoryNode.Parent;

            var nodesToDelete = this.SelectedCategoryNode.GetDescendants();
            foreach (Category category in from node in nodesToDelete where node.AssociatedObject != null select node.AssociatedObject as Category)
            {
                this._categoryRepository.Remove(category.UniqueCode);
            }

            parent.Children.Remove(this.SelectedCategoryNode);

            this.RefreshCategoryTree();
        }

        #endregion

        #endregion

        #region Service

        private void OnCreateNewServiceEventSubscribed(Service service)
        {
            if (this.SelectedCategoryNode == null)
            {
                MessageBoxContext messageBoxContext = new MessageBoxContext("Please select a Category first",
                                                                            GlobalInfoCaches.AssemblyName,
                                                                            MessageBoxButtons.OK,
                                                                            MessageBoxIcons.Exclamation);
                this.ShowMessageBox.Raise(messageBoxContext,
                                          boxContext => { },
                                          () => { });
            }

            Category selectedCategory = this.SelectedCategoryNode.AssociatedObject as Category;
            IEnumerable<Category> categories = this._categoryRepository.Get(c => c.IsValid);
            ServiceDataContext serviceDataContext = new ServiceDataContext(selectedCategory, new ObservableCollection<Category>(categories), false);

            this.CreateNewServiceNotification.Raise(service, serviceDataContext, this.CreateNewServiceCallback, ()=> { });
        }

        private void CreateNewServiceCallback(Service service)
        {
            this._serviceRepository.Add(service);
            this._serviceRepository.Save();
        }

        private void OnEditServiceEventSubscribed(object parameter)
        {
            if (this.SelectedService == null)
            {
                MessageBoxContext context = new MessageBoxContext("Please select a Service to edit first.",
                                                                  GlobalInfoCaches.AssemblyName, MessageBoxButtons.OK,
                                                                  MessageBoxIcons.Exclamation);
                this.ShowMessageBox.Raise(context, 
                                          boxContext => { },
                                          () => { });

                return;
            }

            Category selectedCategory = this.SelectedService.AssociatedCategory as Category;
            IEnumerable<Category> categories = this._categoryRepository.Get(c => c.IsValid);
            ServiceDataContext serviceDataContext = new ServiceDataContext(selectedCategory, new ObservableCollection<Category>(categories), true);

            this.CreateNewServiceNotification.Raise(this.SelectedService, serviceDataContext, this.EditServiceCallback, ()=> { });
        }

        private void EditServiceCallback(Service service)
        {
            this._serviceRepository.Remove(service.UniqueCode);
            this._serviceRepository.Add(service);
            this._serviceRepository.Save();
        }

        private void OnDeleteServiceEventSubscribed(MessageBoxContext context)
        {

        }

        #endregion
    }
}
